﻿@using System.IO
@using System.Text
@using System.Threading
@using FluentValidation

@namespace MudBlazor.Docs.Examples

@inject ISnackbar Snackbar

<MudStack Style="width: 100%">
    <MudForm Model="@_model"
             @bind-IsValid="_isValid"
             @bind-IsTouched="_isTouched"
             Validation="@_validationRules.ValidateValue">
        <MudItem xs="12">
            <MudFileUpload T="IReadOnlyList<IBrowserFile>"
                           AppendMultipleFiles
                           @bind-Files="_model.Files"
                           @bind-Files:after="@ClearDragClass"
                           For="@(() => _model.Files)"
                           Hidden="@false"
                           InputClass="absolute mud-width-full mud-height-full overflow-hidden z-20"
                           InputStyle="opacity:0"
                           @ondragenter="@SetDragClass"
                           @ondragleave="@ClearDragClass"
                           @ondragend="@ClearDragClass">
                <ButtonTemplate>
                    <MudPaper Height="300px"
                              Outlined="true"
                              Class="@_dragClass">
                        <MudText Typo="Typo.h6">
                            Drag and drop files here or click
                        </MudText>
                        @foreach (var file in _model.Files?.Select(file => file.Name) ?? Enumerable.Empty<string>())
                        {
                            <MudChip Color="Color.Dark"
                                     Text="@file" />
                        }
                    </MudPaper>
                    <MudToolBar DisableGutters="true"
                                Class="relative d-flex justify-end gap-4 z-30">
                        <MudButton HtmlTag="label"
                                   Color="Color.Primary"
                                   for="@context.Id"
                                   Variant="Variant.Filled">
                            Open file picker
                        </MudButton>
                        <MudButton OnClick="@Upload"
                                   Color="Color.Primary"
                                   Disabled="@(!_isValid || !_isTouched || _model.Files is null || !_model.Files.Any())"
                                   Variant="Variant.Filled">
                            Upload
                        </MudButton>
                        <MudButton OnClick="@context.Actions.ClearAsync"
                                   Color="Color.Error"
                                   Disabled="@(_model.Files is null || !_model.Files.Any())"
                                   Variant="Variant.Filled">
                            Clear
                        </MudButton>
                    </MudToolBar>
                </ButtonTemplate>
            </MudFileUpload>
        </MudItem>
        <MudItem xs="12">
            IsValid: @_isValid - IsTouched: @_isTouched
        </MudItem>
    </MudForm>
</MudStack>

@code {
#nullable enable
    public class Model
    {
        public IReadOnlyList<IBrowserFile>? Files { get; set; } = new List<IBrowserFile>();
    }

    private Model _model =  new();
    private ModelFluentValidator _validationRules = new();
    private bool _isValid;
    private bool _isTouched;
    private const string FileContent = "this is content";
    private const string DefaultDragClass = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full z-10";
    private string _dragClass = DefaultDragClass;

    private void Upload()
    {
        // Upload the files here
        Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
        Snackbar.Add("TODO: Upload your files!");
    }

    private void SetDragClass()
        => _dragClass = $"{DefaultDragClass} mud-border-primary";

    private void ClearDragClass()
        => _dragClass = DefaultDragClass;

    public class ModelFluentValidator : AbstractValidator<Model>
    {
        public ModelFluentValidator()
        {
            RuleFor(x => x.Files)
                .NotEmpty()
                .WithMessage("There must be at least 1 file.");
        }

        public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
        {
            var result = await ValidateAsync(ValidationContext<Model>.CreateWithOptions((Model)model, x => x.IncludeProperties(propertyName)));
            return result.IsValid ? Array.Empty<string>() : result.Errors.Select(e => e.ErrorMessage);
        };
    }
}